package com.lvy.hczn.transmit.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lvy.hczn.front.common.constant.MqConstants;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.system.domain.business.TransferOrder;
import com.lvy.hczn.front.system.domain.business.Warehouse;
import com.lvy.hczn.front.system.domain.business.dto.OperationBitDto;
import com.lvy.hczn.front.system.service.WarehouseService;
import com.lvy.hczn.mq.rocket.ParamInfo;
import com.lvy.hczn.mq.rocket.ProducerUtil;
import com.lvy.hczn.transmit.service.TOperationBitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @description: 操作位同步业务类
 * @projectName: wms-front
 * @package: com.lvy.hczn.transmit.service.impl
 * @className: TOperationBitServiceImpl
 * @author: yw
 * @date: 2025/4/24 9:59
 */
@Service
@Slf4j
public class TOperationBitServiceImpl implements TOperationBitService {

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private ProducerUtil producerUtil;

    /**
     * 从平台同步操作位
     *
     * @param info 包含操作位信息的参数对象
     * @throws RuntimeException 当参数校验失败时抛出
     * @throws UtilException    当仓库查询或消息发送失败时抛出
     */
    @Override
    public void syncOperationBitPlatform(ParamInfo<OperationBitDto> info) {
        // 参数基础校验
        validateBasicParams(info);

        // 创建新的参数对象并设置数据
        ParamInfo<OperationBitDto> paramInfo = createValidatedParamInfo(info);

        // 获取仓库信息并发送消息
        sendOperationBitMessage(info.getWarehouseCode(), paramInfo);
    }

    /**
     * 验证基础参数
     */
    private void validateBasicParams(ParamInfo<OperationBitDto> info) {
        if (info == null || (info.getData() == null && (info.getList() == null || info.getList().isEmpty()))) {
            throw new RuntimeException("参数为空");
        }

        if (StrUtil.isEmpty(info.getWarehouseCode())) {
            throw new RuntimeException("仓库编号为空");
        }
    }

    /**
     * 创建并验证参数信息
     */
    private ParamInfo<OperationBitDto> createValidatedParamInfo(ParamInfo<OperationBitDto> info) {
        ParamInfo<OperationBitDto> paramInfo = new ParamInfo<>();

        if (info.getList() != null && !info.getList().isEmpty()) {
            List<OperationBitDto> list = castToOperationBitDtoList(info.getList());
            validateOperationBitList(list, info.getWarehouseCode());
            paramInfo.setList(list);
        } else {
            validateSingleOperationBit(info.getData());
            info.getData().setWarehouseCode(info.getWarehouseCode());
            if (StrUtil.isEmpty(info.getData().getName())) {
                info.getData().setName(info.getData().getSortCode() + "号操作位");
            }
            paramInfo.setData(info.getData());
        }

        return paramInfo;
    }

    /**
     * 安全转换为OperationBitDto列表
     */
    @SuppressWarnings("unchecked")
    private List<OperationBitDto> castToOperationBitDtoList(Object data) {
        try {
            return (List<OperationBitDto>) data;
        } catch (ClassCastException e) {
            throw new RuntimeException("数据类型转换异常", e);
        }
    }

    /**
     * 验证操作位列表
     */
    private void validateOperationBitList(List<OperationBitDto> list, String warehouseCode) {
        if (list == null || list.isEmpty()) {
            throw new RuntimeException("操作位列表为空");
        }

        for (OperationBitDto dto : list) {
            validateOperationBit(dto);
            if (StrUtil.isEmpty(dto.getName())) {
                dto.setName(dto.getSortCode() + "号操作位");
            }
            dto.setWarehouseCode(warehouseCode);
        }
    }

    /**
     * 验证单个操作位
     */
    private void validateSingleOperationBit(OperationBitDto dto) {
        if (dto == null) {
            throw new RuntimeException("操作位为空");
        }
        validateOperationBit(dto);
    }

    /**
     * 通用的操作位验证逻辑
     */
    private void validateOperationBit(OperationBitDto dto) {
        if (dto.getId() == null || dto.getId().isEmpty()) {
            throw new RuntimeException("操作位ID为空");
        }
        if (dto.getType() == null) {
            throw new RuntimeException("操作位类型为空");
        }
        if (dto.getSortCode() == null) {
            throw new RuntimeException("操作位编码为空");
        }
    }

    /**
     * 发送操作位消息
     */
    private void sendOperationBitMessage(String warehouseCode, ParamInfo<OperationBitDto> paramInfo) {
        Warehouse warehouse = warehouseService.getOne(Wrappers.<Warehouse>lambdaQuery()
                .eq(Warehouse::getWarehouseCode, warehouseCode)
                .last("limit 1"));

        if (warehouse == null) {
            throw new UtilException("仓库编码" + warehouseCode + "未查询到仓库信息");
        }

        String topic = warehouseService.selectRegionAreaTopic(warehouse);
        String tag = warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_OPERATION_BIT;

        try {
            producerUtil.sendAsyncMsg(topic, tag, JSON.toJSONString(paramInfo).getBytes(StandardCharsets.UTF_8), IdUtil.fastSimpleUUID());
        } catch (Exception e) {
            throw new UtilException("数据发送异常", e);
        }
    }

}
